<?php
namespace App\Http\Logic;

use App\Models\SwtOrder;
use App\Models\SwtTradeAccount;
use App\Models\SwtTradeAccountLog;
use App\Models\SwtTradeAddress;
use Illuminate\Support\Facades\DB;
use Ramsey\Uuid\Uuid;

class OrderLogic extends BaseLogic
{

    public static function create(array $params) : bool
    {
        $account_id = SwtTradeAccount::where('user_id', $params['user_id']) -> where('type',0) -> value('id');

        if(!$account_id) {
            self::$error = __('coin-type.trade_not_found');
            return false;
        }

        DB::beginTransaction();
        try {
            $inst_arr = explode("-",$params["instId"]);

            $data = [
                "order_sn"    => Uuid::uuid4(),
                "user_id"     => $params["user_id"],
                "inst_id"     => $params["instId"],
                "base_ccy"    => $inst_arr[0],
                "quote_ccy"   => $inst_arr[1],
                "price"       => $params['price'],
                "num"         => $params['num'],
                "type"        => $params['type'],
            ];

            $order_info = SwtOrder::create($data);

            if(!$order_info) {
                throw new \Exception(__('order.order_create_fail'));
            }

            $where = [
                "user_id"     => $params["user_id"],
                "account_id"  => $account_id,
            ];

            $base_info = SwtTradeAddress::where($where) -> where('chain_name', $inst_arr[0]) -> first();

            $quote_info = SwtTradeAddress::where($where) -> where('chain_name', $inst_arr[1]) -> first();

            if($params['type'] == 0) {
                if($quote_info -> total < $params['num'] * $params['price']) {
                    throw new \Exception(__("order.insufficient_balance"));
                }
                $base_info -> total += $params['num'];
                $quote_info -> total -= $params['num'] * $params['price'];
                $text = '{buy}'.$params['num'].' '.$inst_arr[0];
            } else {
                if($base_info -> total < $params['num']) {
                    throw new \Exception(__('order.insufficient_balance'));
                }
                $base_info -> total -= $params['num'];
                $quote_info -> total += $params['num'] * $params['price'];
                $text = '{sale}'.$params['num'].' '.$inst_arr[0];
            }

            $res = $base_info -> save();

            if(!$res) {
                throw new \Exception(__("order.num_save_error"));
            }

            $res = $quote_info -> save();

            if(!$res) {
                throw new \Exception(__("order.num_save_error"));
            }

            $log_data = [
                [
                    'address_id'    => $base_info -> id,
                    'user_id'       => $params['user_id'],
                    'source_type'   => 0,
                    'source_id'     => $order_info -> id,
                    'text'          => $text,
                    'change_type'   => $params['type'] == 0 ? 0 : 1,
                    'change_amount' => $params['num'],
                    'created_at'    => now(),
                    'updated_at'    => now()
                ],
                [
                    'address_id'    => $quote_info -> id,
                    'user_id'       => $params['user_id'],
                    'source_type'   => 0,
                    'source_id'     => $order_info -> id,
                    'text'          => $text,
                    'change_type'   => $params['type'] == 0 ? 1 : 0,
                    'change_amount' => $params['num'] * $params['price'],
                    'created_at'    => now(),
                    'updated_at'    => now()
                ]
            ];

            $res = SwtTradeAccountLog::insert($log_data);

            if(!$res) {
                throw new \Exception(__('order.log_add_error'));
            }

            DB::commit();

            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            self::$error = $e->getMessage();
            return false;
        }
    }

    public static function list(int $user_id, int $pageSize = 15, int $pageNo = 1) : array
    {
        $orders = SwtOrder::where('user_id', $user_id) -> orderBy('id','desc');

        $pages = $orders -> paginate(
            perPage: $pageSize,
            columns: ['*'],
            pageName: 'pageNo',
            page: $pageNo
        );

        $list = $orders -> get();

        return [
            'list'        => $list,
            'pageNo'      => $pages->currentPage(),
            'pageSize'    => $pages->perPage(),
            'count'       => $pages->total(),
            'noMore'      => !$pages->hasMorePages(),
        ];
    }
}
